unit PacketData;

interface

uses
  Classes, Windows, SysUtils;

Type
  TPacketData = Class
    private
      FStream, FStreamTmp: TMemoryStream;
      procedure Clear;
      function GetData: pointer;
      function GetSize: int64;
    public
      function Add(Command:integer; Data:Pointer; Size:int64): TMemoryStream; overload;
      function Add(Command:integer; Data:String): TMemoryStream; overload;
      function Add(Command:integer; Data:integer): TMemoryStream; overload;
      procedure Get(Src:TMemoryStream; var Data: pointer; var Size:int64; var Command:integer);

      Constructor Create;
      Destructor  Destroy; override;

      property Stream:TMemoryStream read FStream;
      property Data:pointer         read GetData;
      property Size:int64           read GetSize;
  End;

implementation

{ TPacketData }


function TPacketData.Add(Command: integer; Data: Pointer;
  Size: int64): TMemoryStream;
begin
  self.Clear;
  FStream.Write(Command, Sizeof(Command));
  if Data <> nil then
  begin
    FStream.Write(Data^, Size);
  end;
  FStream.Position := 0;
  Result := FStream;
end;

function TPacketData.Add(Command: integer; Data: String): TMemoryStream;
begin
  self.Clear;
  FStream.Write(Command, Sizeof(Command));
  FStream.Write(Data[1], Length(Data));
  FStream.Position := 0;
  Result := FStream;
end;

function TPacketData.Add(Command, Data: integer): TMemoryStream;
begin
  self.Clear;
  FStream.Write(Command, Sizeof(Command));
  FStream.Write(Data, Sizeof(Data));
  FStream.Position := 0;
  Result := FStream;
end;

procedure TPacketData.Clear;
begin
  FStream.Clear;
end;

constructor TPacketData.Create;
begin
  FStream    := TMemoryStream.Create;
  FStreamTmp := TMemoryStream.Create;

end;

destructor TPacketData.Destroy;
begin
  FreeAndNil( FStream );
  FreeAndNil( FStreamTmp );
  inherited;
end;

procedure TPacketData.Get(Src:TMemoryStream; var Data: pointer; var Size:int64; var Command:integer);
begin
  Data := nil;
  self.clear;
  size := 0;

  if src.Size = 0 then Exit;

  src.Position := 0;
  src.Read(Command, sizeof(integer));

  if src.Position < src.Size then
  begin
    Size := src.Size - sizeof(integer);
    GetMem(Data, Size);
    Windows.ZeroMemory(Data, Size);
    src.Read(Data^, Size);
  end;
end;


function TPacketData.GetData: pointer;
begin
  Result := FStream.Memory;
end;

function TPacketData.GetSize: int64;
begin
  Result := FStream.Size;
end;

end.
